home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dr. Windows 3
/
dr win3.zip
/
dr win3
/
PROGRAMR
/
OLE2BOOK.ZIP
/
CHAP08.ZIP
/
CHAP08
/
SCHMOO
/
IDROPTGT.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-18
|
10KB
|
374 lines
/*
* IDROPTGT.CPP
*
* Implementation of the IDropTarget interface.
*
* Copyright (c)1993 Microsoft Corporation, All Rights Reserved
*
* Kraig Brockschmidt, Software Design Engineer
* Microsoft Systems Developer Relations
*
* Internet : kraigb@microsoft.com
* Compuserve: >INTERNET:kraigb@microsoft.com
*/
#include "schmoo.h"
/*
* CDropTarget::CDropTarget
* CDropTarget::~CDropTarget
*
* Constructor Parameters:
* pDoc LPCSchmooDoc of the document containing us.
*/
CDropTarget::CDropTarget(LPCSchmooDoc pDoc)
{
m_cRef=0;
m_pDoc=pDoc;
m_pIDataObject=NULL;
return;
}
CDropTarget::~CDropTarget(void)
{
return;
}
/*
* CDropTarget::QueryInterface
* CDropTarget::AddRef
* CDropTarget::Release
*
* Purpose:
* IUnknown members for CDropTarget object.
*/
STDMETHODIMP CDropTarget::QueryInterface(REFIID riid, LPVOID FAR *ppv)
{
*ppv=NULL;
//Any interface on this object is the object pointer.
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDropTarget))
*ppv=(LPVOID)this;
/*
* If we actually assign an interface to ppv we need to AddRef it
* since we're returning a new pointer.
*/
if (NULL!=*ppv)
{
((LPUNKNOWN)*ppv)->AddRef();
return NOERROR;
}
return ResultFromScode(E_NOINTERFACE);
}
STDMETHODIMP_(ULONG) CDropTarget::AddRef(void)
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CDropTarget::Release(void)
{
ULONG cRefT;
cRefT=--m_cRef;
if (0L==m_cRef)
delete this;
return cRefT;
}
/*
* CDropTarget::DragEnter
*
* Purpose:
* Indicates that data in a drag operation has been dragged over our
* window that's a potential target. We are to decide if it's something
* we're interested in or not.
*
* Parameters:
* pIDataSource LPDATAOBJECT providing the source data.
* grfKeyState DWORD flags indicating states of keys and mouse buttons.
* pt POINTL coordinates in the client space of the document.
* pdwEffect LPDWORD into which we'll place the appropriate effect
* flag for this point.
*
* Return Value:
* SCODE NOERROR
*/
STDMETHODIMP CDropTarget::DragEnter(LPDATAOBJECT pIDataSource
, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
{
HWND hWnd;
/*
* 1. Use IDataObject::EnumFormatEtc and IDataObject::QueryGetData
* to determine if it has usable data. The conditions for a drop
* are generally the same as for pasting. If pasting isn't possible,
* store DROPEFFECT_NONE in *pdwEffect and return NOERROR.
*
* 2. Determine if you can drop on the point in pt. If not, store
* DROPEFFECT_NONE in *pdwEffect and return NOERROR.
*
* 3. Determine what effect a drop may have at pt and store the
* effect flag in pdwEffect.
*
* 4. If you want IDataObject in DragOver, save it and AddRef
* it here.
*
* 5. Provide some user feedback and return NOERROR.
*/
/*
* 1. Check if we can paste from the pIDataSource we're provided.
* We already made this nice useful function to test.
*/
m_pIDataObject=NULL;
if (!m_pDoc->FQueryPasteFromData(pIDataSource))
{
*pdwEffect=DROPEFFECT_NONE;
return NOERROR;
}
//2. We can always drop anywhere in our document, so pt is uninteresting.
/*
* 3. We return either a COPY or MOVE effect flag, depending on the
* state of the grfKeyState flags. We MOVE on no key or Shift key,
* COPY on Ctrl key.
*/
//Default is move
*pdwEffect=DROPEFFECT_MOVE;
if (grfKeyState & MK_CONTROL)
*pdwEffect=DROPEFFECT_COPY;
/*
* 4. We really don't need to keep the IDataObject around since we're
* not interested in it in DragOver. However, we'll save it just
* for demonstration.
*/
m_pIDataObject=pIDataSource;
m_pIDataObject->AddRef();
/*
* 5. We always accept drops of our data on us, so we only need to
* provide some UI feedback here which we do by inverting the edge
* of the polyline window in this document. We'll remove this in
* DragLeave and in Drop. DragOver won't effect it since we can
* always drop.
*
* Since we're inverting a border, insure that this window is on top.
*/
hWnd=m_pDoc->Window();
BringWindowToTop(hWnd);
UpdateWindow(hWnd);
m_pDoc->DropSelectTargetWindow();
return NOERROR;
}
/*
* CDropTarget::DragOver
*
* Purpose:
* Indicates that the mouse was moved inside the window represented
* by this drop target. This happens on every WM_MOUSEMOVE, so this
* function should be very efficient.
*
* Parameters:
* grfKeyState DWORD providing the current keyboard and mouse states
* pt POINTL where the mouse currently is.
* pdwEffect LPDWORD in which to store the effect flag for this point.
*
* Return Value:
* SCODE NOERROR
*/
STDMETHODIMP CDropTarget::DragOver(DWORD grfKeyState, POINTL pt
, LPDWORD pdwEffect)
{
/*
* 1. Check if dropping is currently kosher at pt given the current
* key states and the data available in the data object. Remember
* if you want a data object here, save and AddRef it in DragEnter.
*
* 2. If you determine you can drop, store the effect flag in pdwEffect
* and provide some sort of visual indication in your window of
* the result of a drop. If the control key is down, the effect
* should be copy instead of move (cut).
*
* 2a. If you are within a scroll inset region defined by
* DragScrollInset, start a timer using DragScrollDelay count.
* When it elapses, scroll your document.
*
* 2b. If you are scrolling and DragOver leaves the inset region,
* stop scrolling.
*
* 3. Return NOERROR.
*/
if (NULL==m_pIDataObject)
{
*pdwEffect=DROPEFFECT_NONE;
return NOERROR;
}
//Since we can always drop, we just return effect flags based on keys.
*pdwEffect=DROPEFFECT_MOVE;
if (grfKeyState & MK_CONTROL)
*pdwEffect=DROPEFFECT_COPY;
return NOERROR;
}
/*
* CDropTarget::DragLeave
*
* Purpose:
* Informs the drop target that the operation has left its window.
*
* Parameters:
* None
*
* Return Value:
* SCODE NOERROR
*/
STDMETHODIMP CDropTarget::DragLeave(void)
{
/*
* 1. If you are scrolling, stop now.
* 2. Remove any UI feedback in your window for potential drop results.
* 3. Release any IDataObject held from DragEnter.
* 4. Return NOERROR.
*/
if (NULL==m_pIDataObject)
return NOERROR;
//1. We don't scroll, so we don't worry about timers.
//2. Remove the UI feedback
m_pDoc->DropSelectTargetWindow();
//3. Release the held IDataObject
m_pIDataObject->Release();
return NOERROR;
}
/*
* CDropTarget::Drop
*
* Purpose:
* Instructs the drop target to paste the data that was just now dropped
* on it.
*
* Parameters:
* pIDataSource LPDATAOBJECT from which we'll paste.
* grfKeyState DWORD providing current keyboard/mouse state.
* pt POINTL at which the drop occurred.
* pdwEffect LPDWORD in which to store what you do with the data.
*
* Return Value:
* SCODE NOERROR
*/
STDMETHODIMP CDropTarget::Drop(LPDATAOBJECT pIDataSource
, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
{
BOOL fRet=TRUE;
/*
* 1. If you have a scrolling timer active, stop it now.